package eg.backend.repository.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import eg.backend.base.repository.EntityRepositoryImpl;
import eg.backend.domain.Expense;
import eg.backend.repository.ExpenseRepository;

public class ExpenseRepositoryImpl extends EntityRepositoryImpl<Expense, String> implements ExpenseRepository {
	@Override
	public Expense get(String identifier) {
		return this.baseDao.get(identifier, Expense.class);
	}

	public List<Expense> findDaily(Date from, Date to, String user) {
		String queryName = "Expense.findDaily";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("from", from);
		queryParams.put("to", to);
		queryParams.put("user", user);
		return this.findByNamedQuery(queryName, queryParams);
	}

	public Date findMaxDate(String user) {
		String queryName = "Expense.findMaxDate";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("user", user);
		List<Date> expenses = baseDao.findRangeByNamedQuery(queryName, 1, queryParams, 0);
		return expenses == null || expenses.size() == 0 ? null : expenses.get(0);
	}

	public Date findMinDate(String user) {
		String queryName = "Expense.findMinDate";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("user", user);
		List<Date> expenses = baseDao.findRangeByNamedQuery(queryName, 1, queryParams, 0);
		return expenses == null || expenses.size() == 0 ? null : expenses.get(0);
	}

	//get expense items precisely on this dimension
	public List<Expense> findChildrenByDimension(String dimensionId) {
		String queryName = "Expense.findChildrenByDimension";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("dimensionId", dimensionId);
		return this.findByNamedQuery(queryName, queryParams);
	}

	public Double getTotalOfCategory(List<String> categories, Date from,
			Date to, String userId) {
		Double sum = 0.0;
		for(String category : categories) {
			String queryName = "Expense.getTotalOfCategory";
			Map<String, Object> queryParams = new HashMap<String, Object>();
			queryParams.put("owner", userId);
			queryParams.put("from", from);
			queryParams.put("to", to);
			queryParams.put("category", category);
			List<Double> amounts = baseDao.findByNamedQuery(queryName, Integer.MAX_VALUE, queryParams);
			for(Double amount : amounts)
				sum += amount;
		}
		return sum;
	}

	public Double getTotalOfTag(Date from, String tagName, Date to, String userId) {
		String queryName = "Expense.getTotalOfTag";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("owner", userId);
		queryParams.put("from", from);
		queryParams.put("to", to);
		queryParams.put("tagName", tagName);
		List<Double> amounts = baseDao.findByNamedQuery(queryName, Integer.MAX_VALUE, queryParams);
		Double sum = 0.0;
		for(Double amount : amounts)
			sum += amount;
		return sum;
	}

}
